<?php
/*
 * 主要功能:
 *
 * 56.com - PHP - class.wc.php
 * coding:夏一平
 * 创建时间:2006-11-28
 */
class ws
{
	private $fileDir 	= C_HTML;
	private $dir		= "web_static";
	private $minSize	= 1024;//最少字节数
	private $level		= 0;
	private $cacheTime	= 300;//秒
	private $outEnd		= ".html";
	///////
	private $filename;
	private $_time;
	private $_make			= false;
	private $_stop			= false;
	private $_tmpFileTime	= 30;//touch最长时间 一般30-60秒
	private $_bug			= false;
	//////
	public function __construct($arr=array(),$config=array(),$parameter= false)
	{
	    $this->_time	= time();
	    $_GET['e'] 
	    	&& $this->_bug = true;
	    $this->set($config);
	    $this->getFileName($arr);
	    $parameter && method_exists($this,$parameter)
	    	&& $this->$parameter();
	    if($parameter)
	    	return;
	    if(is_file($this->filename) 
	    	&& $_SERVER["HTTP_CACHE_CONTROL"] != 'no-cache'  
	    	&& $_SERVER["HTTP_PRAGMA"] 		  != 'no-cache')
	    {
	        $fileMTime 	= filemtime($this->filename);
			$fileMSize 	= filesize($this->filename);
			if($fileMTime<$this->_time-$this->cacheTime
				|| ($fileMSize> 0 && $fileMSize<$this->minSize)
				|| ($fileMSize==0 && $fileMTime<$this->_time-$this->_tmpFileTime))
			{
			    $this->_make	= true;
			}
	    }else
	    {
	        $this->_make	= true;
	    }
	    if($this->_make)
	    {
	        touch($this->filename);
	        ob_start(array(&$this, 'callback'));
			ob_implicit_flush(1);
	    }else
	    {
	        $fileMTime && $etag = md5((int)$fileMTime/10);
	        if($etag && $etag == $_SERVER["HTTP_IF_NONE_MATCH"])
	        {
	            header("Etag: ".$etag,true,304);
	        }else
	        {
		        header("Expires: ".gmdate("D, d M Y H:i:s", $this->_time+$this->cacheTime)." GMT");
				header("Cache-Control: max-age=".$this->cacheTime);
				header("Last-Modified: " . gmdate("D, d M Y H:i:s",$fileMTime) . " GMT");
				header("Etag: ".$etag);
				$this->_bug && header("xypin: ".$this->filename);
				readfile($this->filename);
	        }
			exit();
	    }
	}
	public function stop()
	{
		$this->_make	= false;
	}
	public function callback(&$buffer)
	{
		$buffer = preg_replace(array('/<!--- [\s\S]*? -->/','/<!-- [\s\S]*? --->/','/\s\s+/','/>\s*/'),array('','',' ','>'),$buffer);
		//$buffer = preg_replace('/>\s*/','>',$buffer);
		//$buffer = preg_replace('/\s\s+/',' ',$buffer);
		if(!$this->_make || strlen($buffer)<$this->minSize)
		{
			header("Expires: ".gmdate("D, d M Y H:i:s", $this->_time)." GMT");
			header("Cache-Control: max-age=0");
			$this->_bug && header("wc_stop: true");
		}else
		{
			$fileMTime = time();
			$etag 	   = md5((int)$fileMTime/10);
			header("Expires: ".gmdate("D, d M Y H:i:s", $this->_time+$this->cacheTime)." GMT");
			header("Cache-Control: max-age=".$this->cacheTime);
			header("Last-Modified: " . gmdate("D, d M Y H:i:s",$fileMTime) . " GMT");
			header("Etag: ".$etag);
			$this->write($buffer);
		}
		$this->_bug && header("xypm: ".$this->filename);
		return $buffer;
	}
	/*
	 * 功能:设定 
	 */
	private function set(&$config)
	{
		if($config && is_array($config))
			foreach($config as $k => $v) 
				$this->$k = $v;
	}
	private function clean()
	{
	    $this->del();
	}
	private function del()
	{
	    file_exists($this->filename) 
	    	&& unlink($this->filename);
		exit();
	}
	private function c()
	{
	    file_exists($this->filename) 
	    	&& unlink($this->filename);
	}
	/*
	 * 功能:写文件
	 */
	private function write(&$content)
	{
		$this->_bug && header("write: 1");
		if($fd=fopen($this->filename,'w'))
		{
			fwrite($fd,$content);			
			fclose($fd);
		}else
		{
		    unlink($this->filename);
		}		
		return;
	}
	/*
	 * 功能:得到文件名
	 */
	private function getFileName($arr)
	{
		if($this->filename)
			return $this->filename;
		$key = array();
		arsort($arr);
		foreach($arr as $k=>&$v) 
			$key[] = $k.'='.urlencode($v);
		$key = implode("&",$key);
		$md5 = abs(crc32($key));
		if($this->level<=5)
		{
			$this->filename =  $this->fileDir.$this->dir."/";  
		}elseif($this->level<=30)
		{
		    $VarOrd1 = $md5%30;
		    $this->filename =  $this->fileDir.$this->dir."/".$VarOrd1."/"; 
		}elseif($this->level<=300)
		{
		    $VarOrd1 = substr($md5,-2,1);	
			$VarOrd2 = substr($md5,-1,1);
			$this->filename =  $this->fileDir.$this->dir."/".$VarOrd1."/".$VarOrd2."/"; 
		}else
		{
		    $VarOrd1 = substr($md5,-4,2);	
			$VarOrd2 = substr($md5,-2,2);
			$this->filename =  $this->fileDir.$this->dir."/".$VarOrd1."/".$VarOrd2."/";
		}
		$this->dir($this->filename,true);
		$this->filename.= $key.$this->outEnd;
		return $this->filename;
	}
	
	private function dir($dir, $recursive= false)
    {
        if (is_dir($dir))
        {
            return true;
        } else
        {
        	file_exists($dir)
        		&& unlink($dir);
        	return mkdir($dir, 0777, $recursive);
        }
    }
}
?>